//
//  HttpHelp.m
//  wowoCircle
//
//  Created by yang on 2019/6/29.
//  Copyright © 2019 com. All rights reserved.
//

#import "HttpHelp.h"
#import "AFNetworking.h"
#import "HttpAPI.h"
#import "MJExtension.h"
#import "AppDelegate.h"
#import "MBProgressHUD+SGQRCode.h"

@interface HttpHelp()

@end

static AFHTTPSessionManager *_manager = nil;

@implementation HttpHelp

+(instancetype)shareInstance{
    static HttpHelp *_sharedSingleton = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _sharedSingleton = [[self alloc] init];
        _manager = [AFHTTPSessionManager manager];
    });
    return _sharedSingleton;
}

- (void)GET:(NSString *)URL param:(NSDictionary *)param result:(void (^)(NSDictionary * _Nonnull))result{
    _manager.requestSerializer = [AFJSONRequestSerializer serializer];
    _manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    [self headerConfig];
    //----------//
    [self URLRequestStringWithURL:URL dic:param header:@""];
    //----------//
    [_manager GET:URL parameters:param headers:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:responseObject options:nil error:nil];
        if(result){
            result(dict);
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    }];
}
-(void)GETHTTP:(NSString *)URLString parameters:(NSDictionary *)parameters result:(void(^)(BOOL network, BOOL finish,NSString *error ,NSDictionary * dict,NSMutableArray *data))result{
    [self GETHTTP:URLString parameters:parameters result:result withModel:nil];
}


//-(void)GETHTTP:(NSString *)URLString parameters:(NSDictionary *)parameters result:(void(^)(BOOL network, BOOL finish,NSString *error ,NSDictionary * dict,NSMutableArray *data))result withModel:(__nullable Class)model{
////    _manager.requestSerializer = [AFJSONRequestSerializer serializer];
//    _manager.responseSerializer = [AFHTTPResponseSerializer serializer];
//    [self headerConfig];
//    //----------//
//    [self URLRequestStringWithURL:URLString dic:parameters header:@""];
//    //----------//
//
//    [_manager GET:[NSString stringWithFormat:@"%@%@",BaseURL,URLString] parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
//        [self judgingNetworkAndBackDataWithModel:model withData:responseObject result:result];
//    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
//        result(NO,NO,[self errorStr:error],nil,nil);
//    }];
//}

-(void)POSTHTTP:(NSString *)URLString parameters:(NSDictionary *)parameters result:(void(^)(BOOL network, BOOL finish,NSString *error, NSDictionary * dict , NSMutableArray *data))result{
    [self POSTHTTP:URLString parameters:parameters result:result withModel:nil];
}

-(void)POSTHTTPNOBaseURL:(NSString *)URLString parameters:(NSDictionary *)parameters result:(void(^)(BOOL network, BOOL finish,NSString *error, NSDictionary * dict , NSMutableArray *data))result{
    [self POSTHTTPNOBaseURL:URLString parameters:parameters result:result withModel:nil];
}

-(void)POSTHTTP:(NSString *)URLString parameters:(NSDictionary *)parameters result:(void(^)(BOOL network, BOOL finish,NSString *error, NSDictionary * dict , NSMutableArray *data))result withModel:(__nullable Class)model{
    [self POSTHTTPNOBaseURL:[NSString stringWithFormat:@"%@%@",BaseURL,URLString] parameters:parameters result:result withModel:model];
}

//-(void)POSTHTTPNOBaseURL:(NSString *)URLString parameters:(NSDictionary *)parameters result:(void(^)(BOOL network, BOOL finish,NSString *error, NSDictionary * dict , NSMutableArray *data))result withModel:(__nullable Class)model{
////    _manager.requestSerializer = [AFJSONRequestSerializer serializer];
//    _manager.responseSerializer = [AFJSONResponseSerializer serializer];
//    [self headerConfig];
//    //----------//
//    [self URLRequestStringWithURL:URLString dic:parameters header:@""];
//    //----------//
//
//    [_manager POST:URLString parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
//        [self judgingNetworkAndBackDataWithModel:model withData:responseObject result:result];
//    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
//        result(NO,NO,[self errorStr:error],nil,nil);
//    }];
//}


///数据解析
-(void)judgingNetworkAndBackDataWithModel:(Class)model withData:(NSData *)responseObject result:(void(^)(BOOL network, BOOL finish,NSString *error, NSDictionary * dict , NSMutableArray *data))result{
    //    NSLog(@"数据%@",responseObject);
    NSDictionary *dict;
    if ([responseObject isKindOfClass:[NSDictionary class]]) {
        dict = (NSDictionary *)responseObject;
    }else{
        dict = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableLeaves error:nil];
    }
    NSString *code = dict[@"code"];
    if (code.intValue == 200) {
        if (model) {
            [self dataAlaynsis:dict withModel:model result:result];
        }else{
            result(YES,YES,dict[@"msg"],dict,nil);
        }
    }else{
        if ([dict[@"code"] integerValue] == 401) {///token过期
            [MBProgressHUD SG_showMBProgressHUDWithOnlyMessage:@"您的账号在其他设备登录或登录验证超时" delayTime:1];
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                [self clearAndGotoLogin];
            });
            return;
        }
        result(YES,NO,dict[@"msg"],dict,nil);
    }
}


-(void)dataAlaynsis:(NSDictionary *)responseObject withModel:(Class)model result:(void(^)(BOOL network, BOOL finish,NSString *error, NSDictionary * dict , NSMutableArray *data))result{
    id value = [responseObject objectForKey:@"data"];
    if ([value isKindOfClass:[NSArray class]]) {
        NSMutableArray *arr = [NSMutableArray array];
        arr = [model mj_objectArrayWithKeyValuesArray:value];
        result(YES,YES,nil,responseObject,arr);
    }else if ([value isKindOfClass:[NSDictionary class]]){
        NSMutableArray *arr = [NSMutableArray array];
        id item = [model mj_objectWithKeyValues:value];
        if (item) {
            [arr addObject:item];
        }
        result(YES,YES,nil,responseObject,arr);
    }else{
        result(YES,NO,@"数据异常",responseObject,nil);
    }
}


#pragma mark - v2 版本

-(void)POSTHTTPV2:(NSString *)URLString
       parameters:(NSDictionary *)parameters
          success:(void(^)(NSDictionary * dict , NSMutableArray *data))success
          failure:(void(^)(BOOL netErr,NSString *error))failure
        withModel:(__nullable Class)model{
    [self POSTHTTPNOBaseURLV2:[NSString stringWithFormat:@"%@%@",BaseURL,URLString] parameters:parameters success:success failure:failure withModel:model];
}

-(void)POSTHTTPV2:(NSString *)URLString
       parameters:(NSDictionary *)parameters
          success:(void(^)(NSDictionary * dict))success
          failure:(void(^)(BOOL netErr,NSString *error))failure{
    [self POSTHTTPNOBaseURLV2:[NSString stringWithFormat:@"%@%@",BaseURL,URLString] parameters:parameters success:^(NSDictionary * _Nonnull dict, NSMutableArray * _Nonnull data) {
        success(dict);
    } failure:failure withModel:nil];
}

-(void)POSTHTTPNOBaseURLV2:(NSString *)URLString
                parameters:(NSDictionary *)parameters
                   success:(void(^)(NSDictionary * dict , NSMutableArray *data))success
                   failure:(void(^)(BOOL netErr,NSString *error))failure
                 withModel:(__nullable Class)model{
    _manager.responseSerializer = [AFJSONResponseSerializer serializer];
    
    [self headerConfig];
    [self URLRequestStringWithURL:URLString dic:parameters header:@""];
    
    [_manager POST:URLString parameters:parameters headers:nil  progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        [self judgingDataV2:model withData:responseObject success:success failure:failure];
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        failure(YES,[self errorStr:error]);
    }];
}

//-(void)POSTHTTPWithFormDataWithUrl:(NSString *)URLString parameters:(NSDictionary *)parameters avatar:(NSArray *)avatar imgName:(NSString *)imgName result:(void(^)(BOOL network, BOOL finish,NSString *error, NSDictionary * dict , NSMutableArray *data))result{
//    _manager.responseSerializer = [AFJSONResponseSerializer serializer];
//    [self headerConfig];
//    [self URLRequestStringWithURL:URLString dic:parameters header:@""];
//    [_manager POST:[NSString stringWithFormat:@"%@%@",BaseURL,URLString] parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
//        for (UIImage *tempImg in avatar) {
//            //图片的二进制数据
//            NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
//            [formatter setDateFormat:@"yyyyMMddhhmmss"];
//            NSString *str = [formatter stringFromDate:[NSDate date]];
//            NSString *tempName = [NSString stringWithFormat:@"%@%d.jpg",str,arc4random()%9999];
//            NSData *data = UIImageJPEGRepresentation(tempImg, 0.5);
//            NSString *imgname = imgName;
//            [formData appendPartWithFileData:data name:imgname fileName:tempName mimeType:@"image/jpg"];
//        }
//    } progress:^(NSProgress * _Nonnull uploadProgress) {
//
//    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
//        NSString *code = responseObject[@"code"];
//        if (code.intValue == 200) {
//            result(YES,YES,responseObject[@"msg"],responseObject,nil);
//        }else{
//            result(YES,NO,responseObject[@"msg"],responseObject,nil);
//        }
//    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
//        result(NO,NO,[self errorStr:error],nil,nil);
//    }];
//}
//
//-(void)POSTHTTPToVideoWithFormData:(NSString *)URLString parameters:(NSDictionary *)parameters video:(NSData *)video videoKey:(NSString *)videoKey result:(void(^)(BOOL network, BOOL finish,NSString *error, NSDictionary * dict , NSMutableArray *data))result{
//    _manager.responseSerializer = [AFJSONResponseSerializer serializer];
//    [self headerConfig];
//    [self URLRequestStringWithURL:URLString dic:parameters header:@""];
//    [_manager POST:[NSString stringWithFormat:@"%@%@",BaseURL,URLString] parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
//        NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
//        [formatter setDateFormat:@"yyyyMMddhhmmss"];
//        NSString *str = [formatter stringFromDate:[NSDate date]];
//        NSString *name = [NSString stringWithFormat:@"%@%u.mp4",str,arc4random()%999];
//        [formData appendPartWithFileData:video name:videoKey fileName:name mimeType:@"video/mp4"];
//    } progress:^(NSProgress * _Nonnull uploadProgress) {
//
//    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
//        NSString *code = responseObject[@"code"];
//        if (code.intValue == 200) {
//            result(YES,YES,responseObject[@"msg"],responseObject,nil);
//        }else{
//            result(YES,NO,responseObject[@"msg"],responseObject,nil);
//        }
//    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
//        result(NO,NO,[self errorStr:error],nil,nil);
//    }];
//}

- (void)downloadFile:(NSString *)URLString withReportName:(NSString *)reportName success:(void (^)(id item))success progress:(void (^)( double sender))progress exception:(void (^)( id JSON))exception{
    /* 创建网络下载对象 */
    AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
    
    NSString * urlStr = URLString;
    /* 下载地址 */
    NSURL *url = [NSURL URLWithString:urlStr];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    /* 下载路径 */
    NSString *path = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject;
    NSString *filePath = [path stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.pdf",reportName]];
    /* 开始请求下载 */
    NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
        //NSLog(@"下载进度：%.0f％", downloadProgress.fractionCompleted * 100);
        if (progress) {
            progress(downloadProgress.fractionCompleted * 100);
        }
    } destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
        return [NSURL fileURLWithPath:filePath];
    } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
        NSLog(@"下载完成");
        if (!error) {
            if (success) {
                success(filePath);
            }
        }else{
            if (exception) {
                exception(error);
            }
        }
    }];
    [downloadTask resume];
}
///数据解析
-(void)judgingDataV2:(Class)model
            withData:(NSDictionary *)responseObject
             success:(void(^)(NSDictionary * dict , NSMutableArray *data))success
             failure:(void(^)(BOOL netErr,NSString *error))failure{
    NSString *code = responseObject[@"code"];
    NSInteger result = [responseObject[@"result"] integerValue];
    //    NSLog(@"%@",responseObject);
    if (code.intValue == 200 || result == 1) {
        if (model) {
            [self dataAlaynsisV2:responseObject withModel:model success:success];
        }else{
            success(responseObject,nil);
        }
    }else{
        if (code.intValue == 601) {///公用报错
            
        }else if (code.intValue == 401){///登录异常 超时
            [self clearAndGotoLogin];
        }
        [MBProgressHUD SG_showMBProgressHUDWithOnlyMessage:responseObject[@"msg"] delayTime:1];
        failure(NO,responseObject[@"msg"]);
    }
}


///二层数据解析
-(void)dataAlaynsisV2:(NSDictionary *)responseObject
            withModel:(Class)model
              success:(void(^)(NSDictionary * dict , NSMutableArray *data))success {
    id value = [responseObject objectForKey:@"data"];
    if ([value isKindOfClass:[NSArray class]]) {
        NSMutableArray *arr = [NSMutableArray array];
        arr = [model mj_objectArrayWithKeyValuesArray:value];
        success(responseObject,arr);
    }else if ([value isKindOfClass:[NSDictionary class]]){
        NSMutableArray *arr = [NSMutableArray array];
        id item = [model mj_objectWithKeyValues:value];
        if (item) {
            [arr addObject:item];
        }
        success(responseObject,arr);
    }else{
        success(responseObject,nil);
    }
}

///头部添加信息
-(void)headerConfig{
    AFHTTPRequestSerializer *requestSerializer = [AFJSONRequestSerializer serializer];
    if (![NSString hhe_isEmpty:[AccountManager shareAccount].loginModel.token]) {
        [requestSerializer setValue:[NSString stringWithFormat:@"Bearer %@",[AccountManager shareAccount].loginModel.token] forHTTPHeaderField:@"Authorization"];
        //        NSLog(@"tocken = %@", [AccountManager shareAccount].loginModel.token);
    }
    _manager.requestSerializer = requestSerializer;
    _manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", @"text/html", nil];
    // 设置超时时间
    [_manager.requestSerializer willChangeValueForKey:@"timeoutInterval"];
    _manager.requestSerializer.timeoutInterval = 15.0f;
    [_manager.requestSerializer didChangeValueForKey:@"timeoutInterval"];
}



///证书安全设置
- (AFSecurityPolicy *)customSecurityPolicy {
    //无条件的信任服务器上的证书
    AFSecurityPolicy *securityPolicy = [AFSecurityPolicy defaultPolicy];
    
    // 客户端是否信任非法证书
    securityPolicy.allowInvalidCertificates = YES;
    
    // 是否在证书域字段中验证域名
    securityPolicy.validatesDomainName = NO;
    
    return securityPolicy;
    
    /*
     #warning 导入证书之后此处要重新设置
     return nil;
     // 先导入证书 证书由服务端生成，具体由服务端人员操作
     NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"mycer" ofType:@"cer"];//证书的路径
     NSData *cerData = [NSData dataWithContentsOfFile:cerPath];
     
     // AFSSLPinningModeCertificate 使用证书验证模式
     AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
     // allowInvalidCertificates 是否允许无效证书（也就是自建的证书），默认为NO
     // 如果是需要验证自建证书，需要设置为YES
     securityPolicy.allowInvalidCertificates = YES;
     
     //validatesDomainName 是否需要验证域名，默认为YES;
     //假如证书的域名与你请求的域名不一致，需把该项设置为NO；如设成NO的话，即服务器使用其他可信任机构颁发的证书，也可以建立连接，这个非常危险，建议打开。
     //置为NO，主要用于这种情况：客户端请求的是子域名，而证书上的是另外一个域名。因为SSL证书上的域名是独立的，假如证书上注册的域名是www.google.com，那么mail.google.com是无法验证通过的；当然，有钱可以注册通配符的域名*.google.com，但这个还是比较贵的。
     //如置为NO，建议自己添加对应域名的校验逻辑。
     securityPolicy.validatesDomainName = NO;
     
     securityPolicy.pinnedCertificates = [[NSSet alloc] initWithObjects:cerData, nil];
     
     return securityPolicy;
     */
    
}


-(void)cancelRequest{
    
    if (_manager.tasks.count > 0) {
        [_manager.tasks makeObjectsPerformSelector:@selector(cancel)];
#ifdef DEBUG
        NSLog(@"取消网络请求");
#else
        
#endif
    }
}


#pragma mark - 封装一个传输参数的字典
///有token的字典
+(NSMutableDictionary*)MakeDictionary{
    NSMutableDictionary * dictResult = [NSMutableDictionary dictionary];
    //    [dictResult setObject:[AccountManager shareAccount].loginModel.token forKey:@"token"];
    return dictResult;
}

///没有token的字典（token放头部，即将弃用）
+(NSMutableDictionary*)MakeDictionaryWithNOToken{
    NSMutableDictionary * dictResult = [NSMutableDictionary dictionary];
    //    [dictResult setValue:@"iOS" forKey:@"platform"];
    return dictResult;
}


#pragma mark - other
-(NSString *)errorStr:(NSError *)error{
    NSString *info = @"";
    if ([error.userInfo.allKeys containsObject:@"NSLocalizedDescription"]) {
        info = [error.userInfo objectForKey:@"NSLocalizedDescription"];
    }else{
        info = error.domain;
    }
    if ([info isEqualToString:@"NSCocoaErrorDomain"]) {
        info = @"找不到服务器";
    }
    if ([info isEqualToString:@"The Internet connection appears to be offline."]) {
        info = @"网络异常";
    }
    
    if ([error.userInfo.allKeys containsObject:AFNetworkingOperationFailingURLResponseDataErrorKey]) {
        NSData *errorData = [error.userInfo objectForKey:AFNetworkingOperationFailingURLResponseDataErrorKey];
        NSString * responseString = [[NSString alloc] initWithData:errorData encoding:NSUTF8StringEncoding];
        NSData *jsonData = [responseString  dataUsingEncoding:NSUTF8StringEncoding];
        NSError *err;
        NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&err];
        if(err){
            NSLog(@"json解析失败：%@",err);
            //            return nil;
        }
        if ([dic.allKeys containsObject:@"msg"]) {
            info = dic[@"message"];
        }
        NSLog(@"responseString = %@",dic);
    }
    [MBProgressHUD SG_showMBProgressHUDWithOnlyMessage:info delayTime:1];
    return info;
}



#pragma mark - URLTest
- (void)URLRequestStringWithURL:(NSString *)urlstr dic:(NSDictionary *)dict header:(NSString *)header{
    
#ifdef DEBUG
    
#else
    return;
#endif
    
#warning 正式包必须移除次方法
    
    NSMutableString *URL = [NSMutableString stringWithFormat:@"%@",urlstr];
    //获取字典的所有keys
    NSArray * keys = [dict allKeys];
    
    //拼接字符串
    for (int j = 0; j < keys.count; j ++){
        NSString *string;
        if (j == 0){
            //拼接时加？
            string = [NSString stringWithFormat:@"?%@=%@", keys[j], dict[keys[j]]];
            
        }else{
            //拼接时加&
            string = [NSString stringWithFormat:@"&%@=%@", keys[j], dict[keys[j]]];
        }
        //拼接字符串
        [URL appendString:string];
        
    }
    //    return URL;
    //    NSLog(@"%@++++\n%@&token=%@\n++++",header,URL,[AccountManager shareAccount].token);
}

#pragma mark - 退出账号到登录界面
-(void)clearAndGotoLogin{
    [[AccountManager shareAccount] logout];
    [APPDELEGATE setupLoginVC];
}

//-(void)DELETEHTTP:(NSString *)URLString parameters:(NSDictionary *)parameters result:(void(^)(BOOL network, BOOL finish,NSString *error, NSDictionary * dict , NSMutableArray *data))result{
//    _manager.responseSerializer = [AFJSONResponseSerializer serializer];
//    [self headerConfig];
//    //----------//
//    [self URLRequestStringWithURL:URLString dic:parameters header:@""];
//    //----------//
//    [_manager DELETE:[NSString stringWithFormat:@"%@%@",BaseURL,URLString] parameters:parameters success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
//        if ([responseObject[@"code"] integerValue] == 200) {
//            result(YES,YES,responseObject[@"msg"],responseObject,nil);
//        }else{
//            result(NO,NO,responseObject[@"msg"],responseObject,nil);
//        }
//    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
//        result(NO,NO,[self errorStr:error],nil,nil);
//    }];
//}

//-(void)PUTHTTP:(NSString *)URLString parameters:(NSDictionary *)parameters result:(void(^)(BOOL network, BOOL finish,NSString *error, NSDictionary * dict , NSMutableArray *data))result{
//    _manager.responseSerializer = [AFJSONResponseSerializer serializer];
//    [self headerConfig];
//    //----------//
//    [self URLRequestStringWithURL:URLString dic:parameters header:@""];
//    [_manager PUT:[NSString stringWithFormat:@"%@%@",BaseURL,URLString] parameters:parameters success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
//        [self judgingNetworkAndBackDataWithModel:nil withData:responseObject result:result];
//    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
//        result(NO,NO,[self errorStr:error],nil,nil);
//    }];
//}

@end
